﻿Imports GrayIris.Utilities.UI.Controls

Public Class frmMain
    '' Tab management helper
    Dim tabManager As TabManager

    '' Check which tab that was last compiled
    Dim lastCompiled As frmEditor = Nothing

    '' MingW directory location
    Dim mingWPath As String = ""

    '' Handle output executatable file.
    Dim WithEvents Run As RunProcess

#Region "Language Pack Methods"
    Public LanguagePack As Language

    ''' <summary>
    ''' Find all supported languages and fill it in Languages menu 
    ''' </summary>
    Private Sub LoadLanguageMenu()
        '' Load all files in "lang" directory
        Dim dir As New IO.DirectoryInfo(Application.StartupPath() & "\langs")
        Dim dirFiles As IO.FileInfo() = dir.GetFiles()

        For Each file As IO.FileInfo In dirFiles
            '' Strip out xml extension, get actual file name, and use it as menu text
            Dim menuLanguageItem As New ToolStripMenuItem(file.Name.Substring(0, file.Name.Length - 4))
            AddHandler menuLanguageItem.Click, AddressOf LanguageMenuHandler
            menuLanguage.DropDownItems.Add(menuLanguageItem)
        Next
    End Sub

    ''' <summary>
    ''' Handle language menu click event and change the language respectively to
    ''' the language menu
    ''' </summary>
    Private Sub LanguageMenuHandler(ByVal sender As Object, ByVal e As EventArgs)
        '' Load language phrases and setting
        LanguagePack = New Language
        LanguagePack.Load(Application.StartupPath() & "\langs\" & sender.Text & ".xml")

        '' Change font and phrases
        TranslateMenu()
        TranslateToolbar()
    End Sub

    ''' <summary>
    ''' Fill main menu bar with loaded language phrase
    ''' </summary>
    Private Sub TranslateMenu()
        '' Change Font
        menuWrapper.Font = LanguagePack.GetFont()

        '' ---------------------
        '' File Menu
        '' ---------------------
        menuFile.Text = LanguagePack.GetPhrase("File")
        menuNewFile.Text = LanguagePack.GetPhrase("New File")
        menuOpenFile.Text = LanguagePack.GetPhrase("Open File")
        menuSave.Text = LanguagePack.GetPhrase("Save").Replace("$f", "")
        menuSaveAs.Text = LanguagePack.GetPhrase("Save As").Replace("$f", "")
        menuClose.Text = LanguagePack.GetPhrase("Close").Replace("$f", "")
        menuExit.Text = LanguagePack.GetPhrase("Exit")

        menuEdit.Text = LanguagePack.GetPhrase("Edit")

        menuBuild.Text = LanguagePack.GetPhrase("Build")
        menuBuildSub.Text = LanguagePack.GetPhrase("Build")
        menuBuildAndRun.Text = LanguagePack.GetPhrase("Build and Run")

        menuLanguage.Text = LanguagePack.GetPhrase("Languages")
    End Sub

    ''' <summary>
    ''' Fill main toolbar with loaded language phrase
    ''' </summary>
    Private Sub TranslateToolbar()
        tsMain.Font = LanguagePack.GetFont()

        tsbRun.Text = LanguagePack.GetPhrase("Run")
        tsbStop.Text = LanguagePack.GetPhrase("Stop")
    End Sub
#End Region


#Region "New File"
    Private Sub menuNewCPPFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuNewCPPFile.Click, tsbNewCPPFile.Click
        Dim defaultTab As YaTabPage = AddNewTab("main.cpp")
        tcEditor.SelectedTab = defaultTab

        CType(defaultTab.Tag, frmEditor).txtCode.Text = _
            "#include <iostream>" & vbNewLine & _
            "using namespace std;" & vbNewLine & _
            "" & vbNewLine & _
            "int main()" & vbNewLine & _
            "{" & vbNewLine & _
            vbTab & "cout << ""Hello World"";" & vbNewLine & _
            "}"
        CType(defaultTab.Tag, frmEditor).txtCode.Focus()
    End Sub

    Private Sub menuNewCFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuNewCFile.Click, tsbNewCFile.Click
        Dim defaultTab As YaTabPage = AddNewTab("main.c")
        tcEditor.SelectedTab = defaultTab

        CType(defaultTab.Tag, frmEditor).txtCode.Text = _
            "#include <stdio.h>" & vbNewLine & _
            "" & vbNewLine & _
            "int main()" & vbNewLine & _
            "{" & vbNewLine & _
            vbTab & "printf(""Hello World"");" & vbNewLine & _
            "}"
        CType(defaultTab.Tag, frmEditor).txtCode.Focus()
    End Sub

    Private Sub menuNewHFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuNewHFile.Click, tsbNewHFile.Click
        Dim defaultTab As YaTabPage = AddNewTab("main.h")
        tcEditor.SelectedTab = defaultTab

        CType(defaultTab.Tag, frmEditor).txtCode.Text = _
            "#ifndef _EDITHERE_" & vbNewLine & _
            "#define _EDITHERE_" & vbNewLine & _
            "" & vbNewLine & _
            "#endif"
        CType(defaultTab.Tag, frmEditor).txtCode.Focus()
    End Sub
#End Region

#Region "Open and Save"
    Private Sub frmMain_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragEnter
        If e.Data.GetDataPresent(DataFormats.FileDrop) Then
            e.Effect = DragDropEffects.Copy
        End If
    End Sub

    Private Sub frmMain_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop
        Dim files() As String = e.Data.GetData(DataFormats.FileDrop)
        OpenFiles(files)
    End Sub

    ''' <summary>
    ''' Open list of files that haven't already opened
    ''' </summary>
    ''' <param name="filenames">List of filename string to open</param>
    Private Sub OpenFiles(ByVal filenames() As String)
        Dim lastTab As YaTabPage = Nothing

        For Each fullFilename As String In filenames
            Dim isFound As Boolean = False
            For Each k As YaTabPage In tcEditor.Controls
                If k.Tag.GetType Is GetType(frmEditor) AndAlso fullFilename = k.Tag.fullFileName Then
                    isFound = True
                    lastTab = k
                    Exit For
                End If
            Next

            If Not isFound AndAlso IO.File.Exists(fullFilename) Then
                '' Create a new tab and using filename as tab caption
                Dim fileName As String = New IO.FileInfo(fullFilename).Name
                lastTab = AddNewTab(fileName)

                '' Read and put it into our editor
                CType(lastTab.Tag, frmEditor).txtCode.Text = IO.File.ReadAllText(fullFilename)

                '' Save neccessary information
                lastTab.Tag.fileName = fileName
                lastTab.Tag.fullFileName = fullFilename
                lastTab.Tag.SetFileChange(False)
            End If
        Next

        '' Set focus on last tab
        If lastTab IsNot Nothing Then
            tcEditor.SelectedTab = lastTab
            CType(lastTab.Tag, frmEditor).txtCode.Focus()
        End If
    End Sub

    Private Sub menuOpenFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuOpenFile.Click, tsbOpen.Click
        '' Prepare dialogbox
        Dim oDialog As New OpenFileDialog
        oDialog.Multiselect = True
        oDialog.Filter = "All files|*.*|C source files|*.c|C++ source files|*.cpp;*.cc;*.cxx;*.c++;*.cp|Header files|*.h;*.hpp;*.rh;*.hh"

        '' Read selected file(s)
        If oDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
            OpenFiles(oDialog.FileNames)
        End If
    End Sub

    Private Sub menuSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuSave.Click, tsbSave.Click
        Dim tab As frmEditor = tabManager.GetSelectedEditor()
        If tab IsNot Nothing Then
            '' Show dialog if this is a new created file
            If tab.fullFileName = "" Then
                Dim oSave As New SaveFileDialog

                oSave.Filter = "C source files|*.c|C++ source files|*.cpp;*.cc;*.cxx;*.c++;*.cp|Header files|*.h;*.hpp;*.rh;*.hh"
                oSave.FileName = tab.fileName

                '' Choose the right filter index
                Select Case tab.fileName.Split(".").Last().ToLower
                    Case "c"
                        oSave.FilterIndex = 1
                    Case "cpp", "cc", "cxx", "c++", "cp"
                        oSave.FilterIndex = 2
                    Case "h", "hpp", "rh", "hh"
                        oSave.FilterIndex = 3
                End Select

                If oSave.ShowDialog() = Windows.Forms.DialogResult.OK Then
                    IO.File.WriteAllText(oSave.FileName, tab.txtCode.Text)

                    Dim fileName As String = New IO.FileInfo(oSave.FileName).Name
                    tcEditor.SelectedTab.Text = fileName

                    tab.fileName = fileName
                    tab.fullFileName = oSave.FileName
                    tab.SetFileChange(False)
                End If
            Else
                Try
                    IO.File.WriteAllText(tab.fullFileName, tab.txtCode.Text)
                    tab.SetFileChange(False)
                Catch ex As Exception
                    MsgBox(ex.Message, MsgBoxStyle.Critical + MsgBoxStyle.OkOnly)
                End Try
            End If
        End If
    End Sub

    Private Sub menuSaveAs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuSaveAs.Click
        Dim tab As frmEditor = tabManager.GetSelectedEditor()
        If tab IsNot Nothing Then
            Dim oSave As New SaveFileDialog

            oSave.Filter = "C source files|*.c|C++ source files|*.cpp;*.cc;*.cxx;*.c++;*.cp|Header files|*.h;*.hpp;*.rh;*.hh"
            oSave.FilterIndex = 2
            oSave.FileName = tab.fileName

            '' Choose the right filter index
            Select Case tab.fileName.Split(".").Last().ToLower
                Case "c"
                    oSave.FilterIndex = 1
                Case "cpp", "cc", "cxx", "c++", "cp"
                    oSave.FilterIndex = 2
                Case "h", "hpp", "rh", "hh"
                    oSave.FilterIndex = 3
            End Select

            If oSave.ShowDialog() = Windows.Forms.DialogResult.OK Then
                IO.File.WriteAllText(oSave.FileName, tab.txtCode.Text)

                Dim fileName As String = New IO.FileInfo(oSave.FileName).Name
                tcEditor.SelectedTab.Text = fileName

                tab.fileName = fileName
                tab.fullFileName = oSave.FileName
                tab.isChanged = False
            End If
        End If
    End Sub
#End Region

#Region "Tabs Management"
    ''' <summary>
    ''' Create new tab object and add it to main editor tab
    ''' </summary>
    ''' <param name="name">Tab caption</param>
    ''' <returns>Created tab</returns>
    Private Function AddNewTab(ByVal name As String) As YaTabPage
        Dim newTab As New YaTabPage
        Dim newForm As New frmEditor

        newTab.Controls.Add(newForm.Panel1)
        newTab.Tag = newForm
        newTab.Text = name
        newForm.associateTab = newTab
        newForm.fileName = name

        tcEditor.Controls.Add(newTab)
        Return newTab
    End Function

    ''' <summary>
    ''' Remove provided tab
    ''' </summary>
    ''' <param name="tab">Tab that you want to remove</param>
    Private Sub RemoveTab(ByVal tab As YaTabPage)
        If tab.Tag Is lastCompiled Then
            If lastCompiled.fullFileName = "" Then
                dgvError.Rows.Clear()
            End If

            lastCompiled = Nothing
        End If

        Dim tabIndex As Integer = tcEditor.Controls.IndexOf(tab)
        tcEditor.Controls.Remove(tab)

        If tcEditor.Controls.Count > 0 Then
            If tcEditor.Controls.Count <= tabIndex Then
                tcEditor.SelectedTab = tcEditor.Controls(tcEditor.Controls.Count - 1)
            Else
                tcEditor.SelectedTab = tcEditor.Controls(tabIndex)
            End If
        End If
    End Sub

    ''' <summary>
    ''' Close provided tab
    ''' </summary>
    ''' <param name="tab">Tab that you want to close</param>
    Private Function CloseTab(ByVal tab As YaTabPage) As Boolean
        If tabManager.IsEditor(tab) Then
            If tcEditor.SelectedTab IsNot tab Then
                tcEditor.SelectedTab = tab
            End If

            Dim tabEditor As frmEditor = tab.Tag
            If tabEditor.isChanged Then
                Dim msg As String
                If tabEditor.fullFileName <> "" Then
                    msg = "Save file """ & tabEditor.fullFileName & """ ?"
                Else
                    msg = "Save file """ & tabEditor.fileName & """?"
                End If

                Select Case MsgBox(msg, MsgBoxStyle.YesNoCancel + MsgBoxStyle.Information)
                    Case MsgBoxResult.Yes
                        menuSave_Click(Nothing, Nothing)
                        RemoveTab(tab)
                        Return True
                    Case MsgBoxResult.No
                        RemoveTab(tab)
                        Return True
                    Case MsgBoxResult.Cancel
                        '' Don't remove the tab
                        Return False
                End Select
            Else
                RemoveTab(tab)
                Return True
            End If
        End If
    End Function

    ''' <summary>
    ''' Close current selected tab
    ''' </summary>
    Private Sub menuClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuClose.Click
        If tcEditor.Controls.Count > 0 Then
            CloseTab(tcEditor.SelectedTab)
        End If
    End Sub

    ''' <summary>
    ''' Close current selected tab
    ''' </summary>
    Private Sub menuTabClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuTabClose.Click
        menuClose_Click(Nothing, Nothing)
    End Sub

    ''' <summary>
    ''' Close all tab except the selected tab
    ''' </summary>
    Private Sub menuTabCloseAllButThis_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuTabCloseAllButThis.Click
        Dim notThis As YaTabPage = tcEditor.SelectedTab

        For i As Integer = tcEditor.Controls.Count - 1 To 0 Step -1
            Dim tab As YaTabPage = tcEditor.Controls(i)

            If tab IsNot notThis Then
                CloseTab(tab)
            End If
        Next
    End Sub

    ''' <summary>
    ''' Close all left tab except the selected tab
    ''' </summary>
    Private Sub menuTabCloseAllLeft_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuTabCloseAllLeft.Click
        If tcEditor.Controls.Count > 0 Then
            Dim thisIndex As Integer = tcEditor.Controls.IndexOf(tcEditor.SelectedTab)

            For i As Integer = thisIndex - 1 To 0 Step -1
                CloseTab(tcEditor.Controls(i))
            Next
        End If
    End Sub

    ''' <summary>
    ''' Close all right tab except the selected tab
    ''' </summary>
    Private Sub menuCloseAllRight_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuCloseAllRight.Click
        If tcEditor.Controls.Count > 0 Then
            Dim thisIndex As Integer = tcEditor.Controls.IndexOf(tcEditor.SelectedTab)

            For i As Integer = tcEditor.Controls.Count - 1 To thisIndex + 1 Step -1
                CloseTab(tcEditor.Controls(i))
            Next
        End If
    End Sub

    ''' <summary>
    ''' Close all tab
    ''' </summary>
    Private Sub menuExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuExit.Click
        Application.Exit()
    End Sub

    ''' <summary>
    ''' Close all tab
    ''' </summary>
    Private Sub frmMain_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        For i As Integer = tcEditor.Controls.Count - 1 To 0 Step -1
            If CloseTab(tcEditor.Controls(i)) = False Then
                e.Cancel = True
                Exit Sub
            End If
        Next
    End Sub
#End Region

#Region "Build Management"
    Private Function Build() As CompileResult
        If tabManager.IsSelectedTabEditor() Then
            '' Change the last compiled form
            Dim tab As frmEditor = tabManager.GetSelectedEditor()
            lastCompiled = tab

            '' Save file to temporary file
            Dim codeEditor As ScintillaNET.Scintilla = tab.txtCode
            Dim fileToCompile As String

            If tab.fullFileName = "" Then
                fileToCompile = Application.StartupPath & "\temp\main.cpp"
                If Not IO.Directory.Exists(Application.StartupPath & "\temp") Then
                    IO.Directory.CreateDirectory(Application.StartupPath & "\temp")
                End If
            Else
                fileToCompile = tab.fullFileName
                tab.SetFileChange(False)
            End If

            IO.File.WriteAllText(fileToCompile, codeEditor.Text)

            '' Compile and output the .exe in the temporary file
            Dim c As New Compiler(mingWPath & "\bin")
            Dim result As CompileResult = c.Build(fileToCompile, fileToCompile.Substring(0, fileToCompile.LastIndexOf(".")) & ".exe", menuLinkWindow.Checked)
            txtRaw.Text = result.Raw

            '' Handle error message
            dgvError.Rows.Clear()
            For Each msg As ErrorMessage In result.Errors
                '' Create error message in data grid view
                Dim row As DataGridViewRow = dgvError.Rows(dgvError.Rows.Add())
                row.Tag = msg
                row.Cells(1).Value = msg.Filename
                row.Cells(2).Value = msg.Line.ToString
                row.Cells(3).Value = msg.Col.ToString

                If msg.ErrorType = ErrorType.ErrorMsg Then
                    row.DefaultCellStyle.ForeColor = Color.Red
                    row.Cells(0).Value = My.Resources._error
                    row.Cells(4).Value = "[Error] " & msg.Message
                Else
                    row.DefaultCellStyle.ForeColor = Color.DarkOrange
                    row.Cells(0).Value = My.Resources._warning
                    row.Cells(4).Value = "[Warning] " & msg.Message
                End If
            Next

            Return result
        Else
            Return Nothing
        End If
    End Function

    Private Sub menuBuildSub_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuBuildSub.Click
        If Run.isAlive Then
            MsgBox("Process is still running. Stop it first.", MsgBoxStyle.Exclamation)
        Else
            Build()
        End If
    End Sub

    Private Sub tsbRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbRun.Click, menuBuildAndRun.Click
        If Run.isAlive Then
            MsgBox("Process is still running. Stop it first.", MsgBoxStyle.Exclamation)
        Else
            Dim result As CompileResult = Build()

            '' If compile without any error, run the .exe
            If result IsNot Nothing AndAlso result.ExitCode = 0 Then
                tsbRun.Enabled = False
                tsbStop.Enabled = True

                Run.Run(result.Output)
            End If
        End If
    End Sub

    Private Sub menuLinkWindow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuLinkWindow.Click
        menuLinkWindow.Checked = Not menuLinkWindow.Checked
    End Sub

    Private Sub Run_Exited() Handles Run.Exited
        tsbRun.Enabled = True
        tsbStop.Enabled = False
    End Sub

    Private Sub tsbStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbStop.Click
        Run.StopProcess()
    End Sub
#End Region

#Region "Errors Management"
    Private Sub menuErrorCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuErrorCopy.Click
        If dgvError.SelectedRows.Count > 0 Then
            Clipboard.SetText(dgvError.SelectedRows(0).Tag.Message)
        End If
    End Sub

    Private Sub menuErrorCopyFull_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuErrorCopyFull.Click
        If dgvError.SelectedRows.Count > 0 Then
            Clipboard.SetText(dgvError.SelectedRows(0).Tag.FullMessage)
        End If
    End Sub

    Private Sub menuErrorGoogle_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuErrorGoogle.Click
        If dgvError.SelectedRows.Count > 0 Then
            System.Diagnostics.Process.Start("https://www.google.com/search?q=" & dgvError.SelectedRows(0).Tag.Message)
        End If
    End Sub

    Private Sub dgvError_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvError.CellDoubleClick
        Dim msg As ErrorMessage = dgvError.Rows(e.RowIndex).Tag

        '' Is the error message come from temporary file that
        '' we merely use for compiling?
        If msg.FullFilename.ToLower = (Application.StartupPath() & "\temp\main.cpp").ToLower() Then
            If lastCompiled IsNot Nothing Then
                tcEditor.SelectedTab = lastCompiled.associateTab
            End If
        Else
            '' Find the correct tab and set it focus
            Dim isFound As Boolean = False
            For i As Integer = 0 To tcEditor.Controls.Count - 1
                Dim editor As frmEditor = tabManager.GetEditorAt(i)
                If editor IsNot Nothing Then
                    If editor.fullFileName.ToLower = msg.FullFilename.ToLower Then
                        tcEditor.SelectedTab = tcEditor.Controls(i)
                        isFound = True
                        Exit For
                    End If
                End If
            Next

            '' If cannot find, open it
            If Not isFound Then
                OpenFiles(New String() {msg.FullFilename})
            End If
        End If

        Dim codeEditor As ScintillaNET.Scintilla = tabManager.GetSelectedEditor().txtCode
        If codeEditor.Lines.Count >= msg.Line Then
            codeEditor.CurrentPos = codeEditor.Lines(msg.Line - 1).StartPosition + msg.Col - 1
        End If
        codeEditor.Focus()
    End Sub
#End Region

    Public Sub HandleCommandLine(ByVal commandLine() As String)
        If commandLine.Count > 0 Then
            If IO.File.Exists(commandLine(0).Trim("""")) Then
                OpenFiles(New String() {commandLine(0)})
                Me.Activate()
            End If
        End If
    End Sub

    Private Sub menuFind_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuFind.Click
        Dim editor As frmEditor = tabManager.GetSelectedEditor()
        If editor IsNot Nothing Then
            editor.txtCode.FindReplace.ShowFind()
        End If
    End Sub

    Private Sub menuReplace_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuReplace.Click
        Dim editor As frmEditor = tabManager.GetSelectedEditor()
        If editor IsNot Nothing Then
            editor.txtCode.FindReplace.ShowReplace()
        End If
    End Sub

    Private Sub menuComment_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuComment.Click
        If tabManager.IsSelectedTabEditor() Then
            Dim editor As ScintillaNET.Scintilla = tabManager.GetSelectedEditor().txtCode

            '' Determine whether it is multile line or single line comment
            '' and call correct method for it
            If editor.Selection.Length > 0 Then
                Comment.MultipleLineComment(editor)
            Else
                Comment.SingleLineComment(editor)
            End If
        End If
    End Sub

    Private Sub menuUncomment_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuUncomment.Click
        If tabManager.IsSelectedTabEditor() Then
            Dim editor As ScintillaNET.Scintilla = tabManager.GetSelectedEditor().txtCode

            '' Determine whether it is multile line or single line uncomment
            '' and call correct method for it
            If editor.Selection.Length > 0 Then
                Comment.MultipleLineUncomment(editor)
            Else
                Comment.SingleLineUncomment(editor)
            End If
        End If
    End Sub


    Private Sub menuSelectAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuSelectAll.Click
        Dim editor As frmEditor = tabManager.GetSelectedEditor()
        If editor IsNot Nothing Then
            editor.txtCode.Selection.Start = 0
            editor.txtCode.Selection.End = editor.txtCode.TextLength
        End If
    End Sub

    Private Sub menuCut_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuCut.Click
        Dim editor As frmEditor = tabManager.GetSelectedEditor()
        If editor IsNot Nothing Then
            editor.txtCode.Clipboard.Cut()
        End If
    End Sub

    Private Sub menuCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuCopy.Click
        Dim editor As frmEditor = tabManager.GetSelectedEditor()
        If editor IsNot Nothing Then
            editor.txtCode.Clipboard.Copy()
        End If
    End Sub

    Private Sub menuPaste_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuPaste.Click
        Dim editor As frmEditor = tabManager.GetSelectedEditor()
        If editor IsNot Nothing Then
            editor.txtCode.Clipboard.Paste()
        End If
    End Sub

    Private Sub menuUndo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuUndo.Click
        Dim editor As frmEditor = tabManager.GetSelectedEditor()
        If editor IsNot Nothing Then
            editor.txtCode.UndoRedo.Undo()
        End If
    End Sub

    Private Sub menuRedo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuRedo.Click
        Dim editor As frmEditor = tabManager.GetSelectedEditor()
        If editor IsNot Nothing Then
            editor.txtCode.UndoRedo.Redo()
        End If
    End Sub

    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        tabManager = New TabManager(Me.tcEditor)

        '' -----------------------------------------
        '' Load default language
        '' -----------------------------------------
        LanguagePack = New Language
        LanguagePack.Load(Application.StartupPath & "\langs\English.xml")

        '' Fill each control with loaded language phrase
        TranslateMenu()
        TranslateToolbar()

        '' Fill menu with availiable languages
        LoadLanguageMenu()

        '' Handle commandline
        Dim commandLine As List(Of String) = Environment.GetCommandLineArgs().ToList()
        commandLine.RemoveAt(0)
        HandleCommandLine(commandLine.ToArray())

        '' Find the correct mingWPath
        If (IO.Directory.Exists(Application.StartupPath & "\mingw")) Then
            mingWPath = Application.StartupPath & "\mingw"
        ElseIf IO.Directory.Exists(Application.StartupPath & "/../../../../mingw") Then
            mingWPath = Application.StartupPath & "/../../../../mingw"
        End If

        Run = New RunProcess(mingWPath & "\bin", Me)

        Me.AllowDrop = True
    End Sub

    Private Sub frmMain_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        If tcEditor.Controls.Count = 0 Then
            menuNewCPPFile_Click(Nothing, Nothing)
        End If
    End Sub

    Private Sub tcEditor_TabChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tcEditor.TabChanged
        Try
            Dim tab As frmEditor = tabManager.GetSelectedEditor()
            If tab IsNot Nothing Then
                tab.txtCode.Focus()
            End If
        Catch ex As Exception
        End Try
    End Sub

    Private lastWindowState As FormWindowState = FormWindowState.Normal
    Private Sub menuFullscreen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuFullscreen.Click
        If menuFullscreen.Checked Then
            '' Back to normal screen
            menuFullscreen.Checked = False
            Me.WindowState = lastWindowState
            Me.FormBorderStyle = Windows.Forms.FormBorderStyle.Sizable

            '' Show toolbar
            menuWrapper.Visible = True
            tsMain.Visible = True
        Else
            lastWindowState = Me.WindowState

            '' Change to fullscreen mode
            menuFullscreen.Checked = True
            Me.WindowState = FormWindowState.Maximized
            Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None

            '' Hide toolbar
            menuWrapper.Visible = False
            tsMain.Visible = False
        End If
    End Sub

    Private Sub TestingToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TestingToolStripMenuItem.Click
        Dim compiler As New Compile
        MsgBox(compiler.CompileOption.Output.ToOutputFile(Application.StartupPath & "\temp\main.cpp"))
        ''compiler.CompileOption.Output.OutputFile = compiler.CompileOption.Output.ToOutputFile(Application.StartupPath & "\temp\main.cpp")
        ''compiler.Complie(mingWPath & "\bin", Application.StartupPath & "\temp\main.cpp")
    End Sub
End Class